package com.example.other;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

/**
 * @author readpage
 * @create 2022-09-12 20:25
 *
 * 注解的使用
 * 1.理解annotation:
 * ①jdk 5.0 新增的功能
 *
 * ②Annotation其实就是代码里的特殊标记，这些标记可以编译，类加载，运行时被读取，
 * 并执行相应的处理。通过使用Annotation,程序员可以在不改变原有逻辑的情况下，在源文件中
 * 嵌入一些补充信息。
 *
 * 2. Annotation的使用示例
 * 示例一: 生成文档相关的注解
 * 示例二: 在编译时进行格式检查(JDK内置的三个基本注解)
 * @Override: 限定重写父类方法，该注解只能用于方法
 * @Deprecated: 用于表示所修饰的元素(类，方法等)已过时。
 * 通常是因为所修饰的结构危险或存在更好的选择
 * 可以标注在类、字段、方法、参数、构造方法，以及局部变量上。作用：告诉编译器忽略指定的警告，不用在编译完成后出现警告信息。
 * @SuppressWarnings: 抑制编译器警告
 *
 * 示例三: 跟踪代码依赖性，实现替代配置文件功能
 *
 * 3.如何自定义注解: 参照@SuppressWarnings定义
 *  ①注解声明为: @interface
 *  ②内部定义成员,通常使用value表示
 *  ③可以指定成员的默认值，使用default定义
 *  ④如果自定义注解没有成员，表明是一个标识作用。
 *
 *  如果注解有成员，在使用注解时，需要指明成员的值。
 *  自定义注解必须配上注解的信息处理流程(使用反射)才有意义
 *  自定义注解通常都会指明两个元注解: Retention、Target
 *
 *  4. jdk提供的4钟原注解
 *  元注解: 对现有的注解进行解释说明的注解
 *  Retention: 指定所修饰的 Annotation 的生命周期: SOURCE\CLASS (默认行为) \ RUNTIME
 *      只有声明为RUNTIME声明周期的注解，才能通过反射获取。
 *  Target: 用于指定被修饰的Annotation 能用于修饰那些程序元素
 *  *******出现的频率低********
 *  Documented: 表示所修饰的注解在被javadoc解析时，保留下来。
 *  Inherited:
 *
 *  5.通过反射来获取注解信息
 *
 */
public class AnnotationTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.walk();

        @SuppressWarnings({"unused", "rawtypes"})
        List<Object> list = new ArrayList<>();
    }

    @Test
    public void testGetAnnotation() {
        Class<Student> clazz = Student.class;
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println(annotation);
        }

    }
}

@Data
@NoArgsConstructor
@MyAnnotation(value = "hi")
class Person {
    private String name;
    private int age;

    @MyAnnotation
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void walk() {
        System.out.println("人走路");
    }

    public void eat() {
        System.out.println("人吃饭");
    }
}

interface Info2 {
    void show();
}

class Student extends Person implements Info2 {
    @Override
    public void walk() {
        System.out.println("学生走路");
    }

    @Override
    public void show() {

    }
}
